package com.hutao.manage.controller;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.alibaba.fastjson.JSONObject;
import com.hutao.manage.component.Config;
import com.hutao.manage.component.MyConfig;
import com.hutao.manage.pojo.CitizensInfo;
import com.hutao.manage.pojo.FirstLevelMedical;
import com.hutao.manage.pojo.HospitalizationNote;
import com.hutao.manage.pojo.ScanFile;
import com.hutao.manage.pojo.UploadScan;
import com.hutao.manage.pojo.UploadScanFile;
import com.hutao.manage.pojo.User;
import com.hutao.manage.service.MedicalRecordService;
import com.hutao.manage.service.ScanFileService;
import com.hutao.manage.service.UploadFileService;
import com.hutao.manage.util.CookieUtils;
import com.hutao.manage.util.DateUtil;
import com.hutao.manage.util.ExceptionUtil;
import com.hutao.manage.util.FileUtil;
import com.hutao.manage.util.GuidUtil;
import com.hutao.manage.util.HttpClientUtil;
import com.hutao.manage.util.ImgUtil;
import com.hutao.manage.util.ListUtil;
import com.hutao.manage.util.ObjectUtil;
import com.hutao.manage.util.PDFUtil;
import com.hutao.manage.util.Result;
import com.hutao.manage.util.StringUtil;
import com.hutao.manage.util.Validator;
import com.hutao.manage.util.disk.DiskManageUtil;


@RequestMapping("/upload")
@Controller
public class S3UploadFileController{
	
	@Autowired
	private UploadFileService uploadFileService;
	

	@Autowired  
    private Config conf;  
	
	@Autowired
	private MyConfig myConfig;
	
	@Autowired  
    private ScanFileService scanFileService; 
	
	private Logger log = LoggerFactory.getLogger(S3UploadFileController.class);
	
	private static long fileSize = 1024*1024*16;

	@Autowired
	private MedicalRecordService medicalRecordService;
	
	
	/**
	 * 本地文件扫描接口
	 * @param file
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/tempUploadFile", method = RequestMethod.POST)
	@ResponseBody
	public Result tempUploadFile(HttpServletRequest request) {
		try{
			 int i=1;
		     UploadScan uploadScan=null;
		     List<ScanFile> scanFiles = new ArrayList<ScanFile>();
		     List<UploadScanFile> uploadScanFiles= new ArrayList<UploadScanFile>();
		     //操作人
		     String operator=request.getParameter("operator");
		     //扫描文件夹
		     String firstGuid=request.getParameter("firstGuid");
		     String scanFolderName=request.getParameter("scanFolderName");
		
			

			//解析器解析request的上下文
	        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext()); 
	        if(multipartResolver.isMultipart(request)) {
	            //再将request中的数据转化成multipart类型的数据
	            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
	            Iterator<String> iter = multiRequest.getFileNames();
	            while(iter.hasNext()) {
	                MultipartFile multipartFile = multiRequest.getFile((String)iter.next());
	                if(null != multipartFile) {
						
						//获取文件名
						String originalFilename=multipartFile.getOriginalFilename();
						System.out.println("originalFilename"+originalFilename);
						//文件名称
						//String foldName=originalFilename.substring(0, originalFilename.lastIndexOf("/"));
						
						//添加uploadScan
						if(i<=1){
							uploadScan=new  UploadScan();
							uploadScan.setCreateUserId(operator);
							//uploadScan.setHospitalId(1);
							//uploadScan.setStatus(1);
							uploadScan.setCreateDate(new Date());
							uploadScan.setFirstLevelMedicalGuid(firstGuid);
							uploadScan.setUploadDate(new Date());
							uploadScan.setOriginalFolder(scanFolderName);
							
							i++;
						}
						//文件流Hash（100位）
						String hashStr = new StringBuffer(GuidUtil.get36SystemHash(new String(multipartFile.getBytes()))).reverse().toString();
						
			
						//获取文件后缀名
						String fileSuffixes = originalFilename.substring(originalFilename.lastIndexOf(".")+1);
						long fileSize = multipartFile.getSize();
						String fileSizeHashStr = GuidUtil.get36SystemHash(fileSize);
						
						//文件Hash
						String fileHash = new StringBuffer(hashStr).append(fileSizeHashStr).toString();
						System.err.println("fileHash：" + fileHash.length());
						if(!scanFileService.isFileExist(fileHash)){
							ScanFile scanFile = new ScanFile();
							scanFile.setFileHash(fileHash);
							String localPath = GuidUtil.getLocalPath(hashStr);
							
							String remoteUrl = GuidUtil.getRemoteUrl(hashStr);
							
							
							//文件摘要后92位  文件摘要hash值 + 文件大小的5位hash值  
							 hashStr = hashStr.substring(8)+fileSizeHashStr.substring(0, 5);
							
							 
							//文件保存路径
							String filePath = conf.getUploadResourcePath() + localPath;
							File destFile = new File(filePath,hashStr+"."+fileSuffixes);
							if(!destFile.exists()){
								File destDir = new File(filePath);
								if(!destDir.exists()){
									destDir.mkdirs();
								}
								multipartFile.transferTo(destFile);
							}
							scanFile.setCreateDate(new Date());
							scanFile.setFileType(fileSuffixes);
							scanFile.setFileName(hashStr+"."+fileSuffixes);
							scanFile.setFileUrl(remoteUrl);
							scanFiles.add(scanFile);
						}
						
						UploadScanFile uploadScanFile=new UploadScanFile();
						uploadScanFile.setFileHash(fileHash);
						uploadScanFile.setOriginalFileName(originalFilename);
						uploadScanFiles.add(uploadScanFile);
					}
				
	            
	            }
	         }
	        if(uploadScan != null){
				uploadFileService.uploadScanImgs(uploadScan, scanFiles, uploadScanFiles);
	        	/*uploadFileService.uploadScanFiles(uploadScan, scanFiles, uploadScanFiles);*/
	        	return new Result(true, "上传成功!",scanFiles);
			}else{
				return new Result(false, "上传数据为空!");
			}
		} catch (Exception e) {
			e.printStackTrace();
			return new Result(false, "上传失败!");
		} 
		
	}
	
	/**
	 * 删除扫描绑定信息
	 * @param firstGuid
	 * @param fileHash
	 * @return
	 */
	@RequestMapping(value = "/deleteScanImg", method = RequestMethod.POST)
	@ResponseBody
	public Result deleteScanImg(String firstGuid,String fileHash){
		Result result = null;
		try {
		  uploadFileService.removeMedImage(firstGuid, fileHash);
		  result = new Result(true,"删除成功!");
		} catch (Exception e) {
			result = new Result(false,"删除失败!");
		}
		return result;
	}
	
	
	/**
	 * 本地浏览器文件上传
	 * @param file
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/localityUploadFile", method = RequestMethod.POST)
	public String localityUploadFile(@RequestParam("files")MultipartFile[] files,HttpServletRequest request) {
		
		try {
			System.out.println("文件数量:"+files.length);
			UploadScan uploadScan=null;
			String currentUser = CookieUtils.getCookieValue(request, "TT_TOKEN");
			List<ScanFile> scanFiles = new ArrayList<ScanFile>();
			List<UploadScanFile> uploadScanFiles= new ArrayList<UploadScanFile>();
			int i=1;
			if(files!=null && files.length>0){
				for (MultipartFile multipartFile : files) {
					//文件原名称
					String originalFilename=multipartFile.getOriginalFilename();
					//文件名称
					String foldName=originalFilename.substring(0, originalFilename.lastIndexOf("/"));
					
					String folderName=foldName.split("/")[0];
					//添加uploadScan
					if(i<=1){
						uploadScan=new  UploadScan();
						uploadScan.setCreateUserId(currentUser);
						uploadScan.setCreateDate(new Date());
						uploadScan.setUploadDate(new Date());
						uploadScan.setOriginalFolder(folderName);
						i++;
					}
					
					//文件流Hash（100位）
					String hashStr = new StringBuffer(GuidUtil.get36SystemHash(new String(multipartFile.getBytes()))).reverse().toString();
					
		
					//获取文件后缀名
					String fileSuffixes = originalFilename.substring(originalFilename.lastIndexOf(".")+1);
					long fileSize = multipartFile.getSize();
					String fileSizeHashStr = GuidUtil.get36SystemHash(fileSize);
					
					//文件Hash
					String fileHash = new StringBuffer(hashStr).append(fileSizeHashStr).toString();
					System.err.println("fileHash：" + fileHash.length());
					if(!scanFileService.isFileExist(fileHash)){
						ScanFile scanFile = new ScanFile();
						scanFile.setFileHash(fileHash);
						String localPath = GuidUtil.getLocalPath(hashStr);
						
						String remoteUrl = GuidUtil.getRemoteUrl(hashStr);
						
						
						//文件摘要后92位  文件摘要hash值 + 文件大小的5位hash值  
						 hashStr = hashStr.substring(8)+fileSizeHashStr.substring(0, 5);
						
						 
						//文件保存路径
						String filePath = conf.getUploadResourcePath() + localPath;
						File destFile = new File(filePath,hashStr+"."+fileSuffixes);
						if(!destFile.exists()){
							File destDir = new File(filePath);
							if(!destDir.exists()){
								destDir.mkdirs();
							}
							multipartFile.transferTo(destFile);
						}
						scanFile.setCreateDate(new Date());
						scanFile.setFileType(fileSuffixes);
						scanFile.setFileName(hashStr+"."+fileSuffixes);
						scanFile.setFileUrl(remoteUrl);
						scanFiles.add(scanFile);
					}
					
					UploadScanFile uploadScanFile=new UploadScanFile();
					uploadScanFile.setFileHash(fileHash);
					uploadScanFile.setOriginalFileName(originalFilename);
					uploadScanFiles.add(uploadScanFile);
				
				}
			}
			if(uploadScan != null){
				uploadFileService.uploadScanFiles(uploadScan, scanFiles, uploadScanFiles);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		
		
		return "forward:/bind/medBind";
		
	}
	
	/**
	 * 本地浏览器文件夹上传
	 * @param file
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/localityUploadFolder", method = RequestMethod.POST)
	public String localityUploadFolder(@RequestParam("files")MultipartFile[] files, HttpServletRequest request, RedirectAttributes attributes) {
		int count = 0;
		//上传失败文件
		StringBuffer uploadfailFiles = new StringBuffer(); 
		
		try {
			System.out.println("文件数量:"+files.length);
			List<UploadScan> uploadScans = new ArrayList<UploadScan>();
			Map<String, UploadScan> uploadScanMap = new HashMap<String, UploadScan>();
			/*UploadScan uploadScan=null;*/
			String currentUser = CookieUtils.getCookieValue(request, "TT_TOKEN");
			
			if(files!=null && files.length>0){
				for (MultipartFile multipartFile : files) {
					//文件原名称
					String originalFilename =multipartFile.getOriginalFilename();
					String fileSuffixes = FileUtil.getSuffixName(multipartFile.getOriginalFilename());
					
					if (!ImgUtil.isPicture(fileSuffixes)) {
						continue;
					}
					
					String[] splits = originalFilename.split("/");
					//文件名
					String fileName =splits[splits.length-1];
					//病案号-住院次数
					String folderName=splits[splits.length-2];
					
					String msg = StringUtil.verifyBatchUpload(folderName);
					if (StringUtils.isNotBlank(msg)) {
						attributes.addFlashAttribute("msg", msg);
						attributes.addFlashAttribute("errorCode", -1);
						return "redirect:/page/uploadify";
					}
					
					UploadScan uploadScan = uploadScanMap.get(folderName);
					if(uploadScan == null){
						uploadScan = new UploadScan();
						uploadScan.setCreateUserId(currentUser);
						uploadScan.setCreateDate(new Date());
						uploadScan.setUploadDate(new Date());
						uploadScan.setOriginalFolder(folderName);
						
						uploadScanMap.put(folderName, uploadScan);
						uploadScans.add(uploadScan);
					}
					
					//文件流Hash（100位）
					String hashStr = new StringBuffer(GuidUtil.get36SystemHash(new String(multipartFile.getBytes()))).reverse().toString();
					
					//获取文件后缀名
					long fileSize = multipartFile.getSize();
					String fileSizeHashStr = GuidUtil.get36SystemHash(fileSize);
					
					//文件Hash
					String fileHash = new StringBuffer(hashStr).append(fileSizeHashStr).toString();
					ScanFile scanFile = new ScanFile();
					scanFile.setFileHash(fileHash);
					String localPath = GuidUtil.getLocalPath(hashStr);
					
					String remoteUrl = GuidUtil.getRemoteUrl(hashStr);
					
					
					//文件摘要后92位  文件摘要hash值 + 文件大小的5位hash值  
					 hashStr = hashStr.substring(8)+fileSizeHashStr.substring(0, 5);
					
					//文件保存路径
					String filePath = conf.getUploadResourcePath() + localPath;
					File destFile = new File(filePath,hashStr+"."+fileSuffixes +"");
					
					//判断文件是否已经存在本地
					if (!DiskManageUtil.isExistsFileInAllDisk(conf.getConfigFileStorageAllDisk(), filePath + hashStr+"."+fileSuffixes)) {
						//File destFile = new File(filePath, hashStr+"."+fileSuffixes);
						
						if (!destFile.exists()) {
							File destDir = new File(filePath);
							if (!destDir.exists()) {
								destDir.mkdirs();
							}
							
							//文件保存到本地 (提示上传失败的文件的名称)
							try {
								multipartFile.transferTo(destFile);
							} catch (IOException ioe) {
								uploadfailFiles.append("[" +originalFilename+ "]" + ",");
								log.error("-------transferTo IOException批量上传文件保存到本地异常------" + ExceptionUtil.getStackTrace(ioe));
							} catch (IllegalStateException iile) {
								uploadfailFiles.append("[" +originalFilename+ "]" + ",");
								log.error("-------transferTo IllegalStateException批量上传文件保存到本地异常------" + ExceptionUtil.getStackTrace(iile));
							}
						}
					}
					
					/*if(!destFile.exists()){
						File destDir = new File(filePath);
						if(!destDir.exists()){
							destDir.mkdirs();
						}
						
						//文件保存到本地 (提示上传失败的文件的名称)
						try {
							multipartFile.transferTo(destFile);
							
						} catch (IOException ioe) {
							uploadfailFiles.append("[" +originalFilename+ "]" + ",");
							log.error("-------transferTo IOException批量上传文件保存到本地异常------" + ExceptionUtil.getStackTrace(ioe));
						} catch (IllegalStateException iile) {
							uploadfailFiles.append("[" +originalFilename+ "]" + ",");
							log.error("-------transferTo IllegalStateException批量上传文件保存到本地异常------" + ExceptionUtil.getStackTrace(iile));
						}
					}*/
					
					scanFile.setOriginalName(fileName);
					scanFile.setCreateDate(new Date());
					scanFile.setFileType(fileSuffixes);
					scanFile.setFileName(hashStr+"."+fileSuffixes);
					scanFile.setFileUrl(remoteUrl);
					uploadScan.getScanFiles().add(scanFile);
				}
			}
			
			Result result = uploadFileService.uploadScanFiles(uploadScans,currentUser);
			
			if (!result.isSuccess()) {
				String msg = result.getMsg();
				attributes.addFlashAttribute("msg", msg);
				attributes.addFlashAttribute("errorCode", result.getStatus());
				return "redirect:/page/uploadify";
			}
			
		} catch (Exception e) {
			log.error("-------批量导入文件上传异常------" + ExceptionUtil.getStackTrace(e));
			e.printStackTrace();
			attributes.addFlashAttribute("errorCode", -3);
			attributes.addFlashAttribute("msg", "批量导入文件上传异常:" + ExceptionUtil.getStackTrace(e));
			return "redirect:/page/uploadify";
		} 
		
		//model.addAttribute("errorCode", count);
		attributes.addFlashAttribute("errorCode", 200);
		return "redirect:/page/uploadify";
	}
	
	
	
	
	
	
	/**
	 * 本地浏览器文件上传
	 * @param file
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/ajaxLocalityUploadFile", method = RequestMethod.POST)
	@ResponseBody
	public Result ajaxMultiUploadFile( HttpServletRequest request,@RequestParam("files")MultipartFile[] files) {
		
		String firstGuid =request.getParameter("firstGuid");
		System.out.println(firstGuid);
		String currentUser = CookieUtils.getCookieValue(request, "TT_TOKEN"); 
		int fileLength = files.length;
		int i=1;
	       UploadScan uploadScan=null;
	       List<ScanFile> scanFiles = new ArrayList<ScanFile>();
			List<UploadScanFile> uploadScanFiles= new ArrayList<UploadScanFile>();
			try {
				for(MultipartFile multipartFile :files){  
		    	    if(null != multipartFile) {
						//获取文件名
						String originalFilename=multipartFile.getOriginalFilename();
						//文件名称
						String foldName=originalFilename.substring(0, originalFilename.lastIndexOf("/"));
						String folderName=foldName.split("/")[0];
						//添加uploadScan
						if(i<=1){
							uploadScan=new  UploadScan();
							uploadScan.setCreateUserId(currentUser);
							uploadScan.setCreateDate(new Date());
							uploadScan.setUploadDate(new Date());
							uploadScan.setOriginalFolder(folderName);
							uploadScan.setFirstLevelMedicalGuid(firstGuid);
							i++;
						}
						//文件流Hash（100位）
						String hashStr = new StringBuffer(GuidUtil.get36SystemHash(new String(multipartFile.getBytes()))).reverse().toString();
						
			
						//获取文件后缀名
						String fileSuffixes = originalFilename.substring(originalFilename.lastIndexOf(".")+1);
						long fileSize = multipartFile.getSize();
						String fileSizeHashStr = GuidUtil.get36SystemHash(fileSize);
						
						//文件Hash
						String fileHash = new StringBuffer(hashStr).append(fileSizeHashStr).toString();
						System.err.println("fileHash：" + fileHash.length());
						if(!scanFileService.isFileExist(fileHash)){
							ScanFile scanFile = new ScanFile();
							scanFile.setFileHash(fileHash);
							String localPath = GuidUtil.getLocalPath(hashStr);
							
							String remoteUrl = GuidUtil.getRemoteUrl(hashStr);
							
							
							//文件摘要后92位  文件摘要hash值 + 文件大小的5位hash值  
							 hashStr = hashStr.substring(8)+fileSizeHashStr.substring(0, 5);
							
							 
							//文件保存路径
							String filePath = conf.getUploadResourcePath() + localPath;
							File destFile = new File(filePath,hashStr+"."+fileSuffixes);
							if(!destFile.exists()){
								File destDir = new File(filePath);
								if(!destDir.exists()){
									destDir.mkdirs();
								}
								multipartFile.transferTo(destFile);
							}
							scanFile.setCreateDate(new Date());
							scanFile.setFileType(fileSuffixes);
							scanFile.setFileName(hashStr+"."+fileSuffixes);
							scanFile.setFileUrl(remoteUrl);
							scanFiles.add(scanFile);
						}
						
						UploadScanFile uploadScanFile=new UploadScanFile();
						uploadScanFile.setFileHash(fileHash);
						uploadScanFile.setOriginalFileName(originalFilename);
						uploadScanFiles.add(uploadScanFile);
					}
				}
				if(uploadScan != null){
					int uploadNum = uploadFileService.uploadScanFileAndBindMedRecord(uploadScan, scanFiles, 
							uploadScanFiles,firstGuid, currentUser);
					return new Result(true, "文件总数:"+fileLength+",上传成功文件数量:"+uploadNum);
				}else{
					return new Result(false, "上传数据为空!");
				}
			} catch (Exception e) {
				e.printStackTrace();
				return new Result(false, "上传失败!");
			}
	}
	
	/**
	 * 
	 * @param file
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/finishUploadVisit", method = RequestMethod.GET)
	@ResponseBody
	public Result finishUploadVisit() {
		Result result = new Result(true, "操作成功!");
		List<Map<String,Object>> datas = uploadFileService.getUploadVisitGuid();
		for (Map<String, Object> data : datas) {
			try{
				String visitGuid = ObjectUtil.getStringValue(data.get("visit_guid"));
				String mrId = ObjectUtil.getStringValue(data.get("mr_id"));
				Integer visitNumber = ObjectUtil.getIntegerValue(data.get("visit_number"));
				String params = "visitGuid="+visitGuid+"&mrId="+mrId+"&visitNumber="+visitNumber;
				String userJson = HttpClientUtil.doGet(myConfig.getExportProjectUrl()+"export305/remote_fetch_data_for_scan?"+params);
				if(userJson != null){
					JSONObject userMap =JSONObject.parseObject(userJson);
					boolean success = userMap.getBoolean("success");
					if(success){
						String filePath = myConfig.getHospitalVisitJsonPath() + StringUtil.getLocalPath(visitGuid);
						String fileName = visitGuid + ".json";
						String currentUser = "yyl";
						Map<String, Object> jsonMap = FileUtil.readLineFile(filePath, fileName);
						if (jsonMap != null) {
							Map<String, Object> examMap = (Map<String, Object>) jsonMap.get("examinationReportsInfo");
							if (examMap != null) {
								List<Map<String, Object>> examinationRecords = (List<Map<String, Object>>) examMap.get("examinationReportsRecords");
								
								if (null != examinationRecords && examinationRecords.size() > 0) {
									List<List<Map<String, Object>>> lists = ListUtil.split(examinationRecords, 2);
									List<String> pdfPathList = new ArrayList<>();
									File tempfile = new File(conf.getExaminationPdfPath() + "temp/");
									if (!tempfile.exists()) {
										tempfile.mkdirs();
									}
									for (int i = 0; i < lists.size(); i++) {
										String guidStr = StringUtil.getId();
										PDFUtil.getPdfByTemplate(lists.get(i), conf.getExaminationPdfPath() + "template.pdf",
												conf.getExaminationPdfPath() + "temp/pdf" + guidStr + ".pdf");
										pdfPathList.add(conf.getExaminationPdfPath() + "temp/pdf" + guidStr + ".pdf");
									}
									
									File file = new File(conf.getUploadResourcePath() + "examination/" + visitGuid + "/");
									if (!file.exists()) {
										file.mkdirs();
									}
									List<String> pdfImageList = PDFUtil.pdf2Image(pdfPathList,
											conf.getUploadResourcePath() + "/examination/" + visitGuid + "/");
									medicalRecordService.addMedicalResourceExaminationForScan(pdfImageList, currentUser, visitGuid,conf.getUploadResourcePath() + "/examination/" + visitGuid + "/");
									//删除并发产生的数据
									medicalRecordService.deleteMreByGroupId(visitGuid, conf.getUploadResourcePath() + "/examination/" + visitGuid + "/");
								}
								
								
							}
						}
					}
				}
			}catch (Exception e) {
				e.printStackTrace();
			}
			
		}
		return result;
	}

}
